package plgdb

import (
	"dgo/MyProj/PrjDBUtils"
	"dgo/MyProj/PrjHttpUtils"
	db_utils "dgo/goutils/db-utils"
	"dgo/goutils/utils"
	"dgo/plg/plgnet"
	"gitee.com/ymofen/gobase"
	"gitee.com/ymofen/supervalue"
	"strings"
	"time"
)

type PlgDbTable2List struct {
	PlgBase
	datasource  string
	selsql      string
	fieldMap    gobase.StrMap
	fieldMapStr string
	innerHttp   *plgnet.InnerHttp
	msglst      *utils.SyncCycleList
}

/*
*

	{
	  "id": "regionlst",
	  "type": "db.table2list",
	  "conf": {
	     "api-prefix":"/varlst/",
	     "datasource":"main",
	     "fieldMap":"attr_=attr."
	     "sql":"select  kpl_ntripuser_info"
	  }
	}
*/
func (this *PlgDbTable2List) ReloadConf(conf *wrapper.SuperValue) error {
	if conf == nil {
		return nil
	}

	conf.CheckExistsStrFunc("fieldMap", func(strv string) {
		if this.fieldMapStr != strv {
			if len(strv) > 0 {
				strMap := gobase.NewStrMap()
				strMap.ParseKVPairsEx(strv, "=", ";", false)
				this.fieldMap = strMap
			} else {
				this.fieldMap = nil
			}
			this.fieldMapStr = strv
		}
	})

	if this.innerHttp == nil {
		this.innerHttp = plgnet.NewInnerHttp(this)
	}
	this.innerHttp.ReloadConf(conf)
	this.innerHttp.CheckRegisterJSONApi("get", func(req *PrjHttpUtils.HttpRec) {
		dao := db_utils.NewDBHelperEx(this.datasource)
		defer dao.Close()
		lvsql := this.selsql
		req.RangeURLParam(func(k, v string) bool {
			if ok, k1 := utils.CheckTrimPrefix(k, "repl_"); ok {
				lvsql = strings.ReplaceAll(lvsql, k1, v)
			}
			return true
		})
		lst := wrapper.NewSVArray()
		rows, err := dao.Query(lvsql)
		if err != nil {
			req.ResponseJSONValues("code", -1, "msg", err.Error())
			return
		}
		defer rows.Close()
		cols, _ := rows.Columns()
		strMap := this.fieldMap
		if strMap != nil && len(strMap) > 0 {
			for i := 0; i < len(cols); i++ {
				for k, v := range strMap {
					cols[i] = strings.ReplaceAll(cols[i], k, v)
				}
			}
		}
		PrjDBUtils.RowsRange(rows, func(idx int, row []db_utils.SqlValue, err error) bool {
			itm := lst.AppendObject()
			for i := 0; i < len(cols); i++ {
				realV := row[i].Value
				switch s := realV.(type) {
				case []byte:
					if len(s) == 1 {
						if s[0] == 0 {
							itm.SetPathValue(cols[i], false)
							break
						} else if s[0] == 1 {
							itm.SetPathValue(cols[i], true)
							break
						}
					}
					itm.SetPathValue(cols[i], string(s))
				case time.Time:
					itm.SetPathValue(cols[i], utils.DateTimeString3(s))
				case nil:
					itm.SetPathValue(cols[i], "")
				default:
					itm.SetPathValue(cols[i], realV)
				}
			}
			return true
		})
		req.ResponseText(lst.String())
	})

	this.datasource = conf.StringByName("datasource", "")
	this.selsql = conf.StringByName("sql", "")

	if this.msglst == nil {
		this.msglst = utils.NewSyncCycleList()
	}

	utils.DefaultPatrolTask().AddTask(this, time.Second*30, func(id interface{}, args ...interface{}) {
		//utils.DefaultWorkers().PostTaskFunc(this, this.innerWork)
	})
	return nil
}

func (this *PlgDbTable2List) Close() (err error) {
	this.PlgBase.Close()
	this.innerHttp.Release()
	utils.DefaultPatrolTask().DelTask(this)
	return
}

func (this *PlgDbTable2List) OnHttpStatus(rec *plgnet.PlgHttpRec) (rval interface{}, errcode int, err error) {
	itype := rec.QryAsInt("type", 0)
	if itype == 99 {
		json := wrapper.NewSVObject()
		json.SetKeyValues("now", utils.NowString())
		if rec.QryAsInt("json", 0) == 1 {
			PrjHttpUtils.ResponseAsJSON(rec.RespW, json.AsJSONStringEx(false, true))
		} else {
			PrjHttpUtils.JSON2TableRec(rec.RespW, "", json.AsJSONString(false))
		}
	} else if itype == 98 {
		rec.ResponseSyncListNEx(this.msglst)
	} else if itype == 1 {
		json := wrapper.NewSVArray()
		//searchval := rec.QryAsString("searchval", "")
		//sn := 0
		//maxn := rec.QryAsInt("n", 100)
		//this.lst.ListRangeV2(func(key, val interface{}) bool {
		//	pojo := val.(*VrsSitePojo)
		//	ok := true
		//	if len(searchval) > 0 {
		//		ok = strings.Contains(pojo.id, searchval)
		//	}
		//	return ok
		//}, func(k0, v0, k1, v1 interface{}) bool {
		//	p0 := v0.(*VrsSitePojo)
		//	p1 := v1.(*VrsSitePojo)
		//	return p0.id < p1.id
		//}, func(key, val interface{}) bool {
		//	sn++
		//	pojo := val.(*VrsSitePojo)
		//	itm := json.AppendObject()
		//	itm.SetKeyValue("sn", sn)
		//	itm.SetKeyValue("id", pojo.id)
		//	return sn < maxn
		//})

		if rec.QryAsInt("json", 0) == 1 {
			PrjHttpUtils.ResponseAsJSON(rec.RespW, json.AsJSONStringEx(false, false))
		} else {
			PrjHttpUtils.JSON2Table(rec.RespW, "", json.AsJSONString(false))
		}
	} else {
		var sb utils.BytesBuilder
		PrjHttpUtils.AppendIndexBody(&sb, "status", "status?type=99")
		PrjHttpUtils.AppendIndexBody(&sb, "msglist", "status?type=98&n=100&searchval=")
		//PrjHttpUtils.AppendIndexBody(&sb, "lst", "status?type=1&n=100&searchval=")
		PrjHttpUtils.ResponseBodyHtml(rec.RespW, sb.String())
	}
	return
}

func (this *PlgDbTable2List) LogInfoMessage(s string, args ...interface{}) {
	this.msglst.LogMsg(s, args...)
	utils.Log.Msgf(this.PlugId, utils.LogLV_INFO, 1, s, args...)
}

func (this *PlgDbTable2List) LogWarnMessage(s string, args ...interface{}) {
	this.msglst.LogMsg(s, args...)
	utils.Log.Msgf(this.PlugId, utils.LogLV_WARN, 1, s, args...)
}

func CreatePlgDbTable2ListFunc(args ...interface{}) (rval interface{}, err error) {
	obj := &PlgDbTable2List{}

	if len(args) > 0 {
		if str, ok := args[0].(string); ok {
			obj.PlugId = str
		}
	}
	rval = obj
	return
}
